<template>
	<div class="test-container">
		<h2>ECharts 平滑热力图测试</h2>
		<div class="heatmap-container" ref="heatmapContainer"></div>
		<div class="controls">
			<button @click="generateTestData">生成测试数据</button>
			<button @click="generateRandomData">生成随机数据</button>
			<button @click="generateSmoothData">生成平滑数据</button>
			<button @click="generateBlendedData">生成混合热力图</button>
		</div>
	</div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts'
import { onBeforeUnmount, onMounted, ref } from 'vue'

const heatmapContainer = ref<HTMLElement | null>(null)
let chart: echarts.ECharts | null = null

onMounted(() => {
	initChart()
	generateSmoothData()
})

onBeforeUnmount(() => {
	if (chart) {
		chart.dispose()
	}
})

const initChart = () => {
	if (!heatmapContainer.value) return
	
	chart = echarts.init(heatmapContainer.value)
	
	// 窗口大小变化时重新调整图表
	window.addEventListener('resize', () => {
		if (chart) {
			chart.resize()
		}
	})
}

const generateTestData = () => {
	if (!chart) return
	
	// 创建测试数据 - 使用散点图方式
	const data = []
	const width = 600
	const height = 400
	
	// 创建几个热点中心
	const hotspots = [
		{ x: 150, y: 200, intensity: 80 },
		{ x: 300, y: 150, intensity: 60 },
		{ x: 450, y: 250, intensity: 70 },
		{ x: 250, y: 300, intensity: 50 }
	]
	
	// 为每个热点生成密集的数据点
	hotspots.forEach(hotspot => {
		// 在热点周围生成大量数据点
		for (let i = 0; i < 200; i++) {
			const radius = Math.random() * 80 // 随机半径
			const angle = Math.random() * Math.PI * 2 // 随机角度
			const x = hotspot.x + Math.cos(angle) * radius
			const y = hotspot.y + Math.sin(angle) * radius
			
			// 根据距离计算强度
			const distance = Math.sqrt((x - hotspot.x) ** 2 + (y - hotspot.y) ** 2)
			const intensity = Math.max(0, hotspot.intensity * Math.exp(-distance / 30))
			
			if (x >= 0 && x <= width && y >= 0 && y <= height && intensity > 1) {
				data.push([x, y, intensity])
			}
		}
	})
	
	// 添加一些随机背景数据
	for (let i = 0; i < 300; i++) {
		data.push([
			Math.random() * width,
			Math.random() * height,
			Math.random() * 8
		])
	}
	
	chart.setOption({
		backgroundColor: '#000',
		title: {
			text: '平滑热力图 - 测试数据',
			left: 'center',
			top: 10,
			textStyle: {
				color: '#fff',
				fontSize: 16
			}
		},
		grid: {
			left: 0,
			right: 0,
			top: 40,
			bottom: 0
		},
		xAxis: {
			type: 'value',
			min: 0,
			max: 600,
			show: false
		},
		yAxis: {
			type: 'value',
			min: 0,
			max: 400,
			show: false
		},
		visualMap: {
			min: 0,
			max: 80,
			show: false,
			inRange: {
				color: [
					'#313695',
					'#4575b4',
					'#74add1',
					'#abd9e9',
					'#e0f3f8',
					'#ffffbf',
					'#fee090',
					'#fdae61',
					'#f46d43',
					'#d73027',
					'#a50026'
				]
			}
		},
		series: [{
			name: '活动强度',
			type: 'scatter',
			data: data,
			symbolSize: function(data: any) {
				// 根据数值大小调整点的大小
				return Math.max(15, Math.min(50, data[2] * 0.8 + 15))
			},
			itemStyle: {
				opacity: 0.6
			},
			label: {
				show: false
			},
			animation: false
		}],
		tooltip: {
			position: 'top',
			backgroundColor: 'rgba(0, 0, 0, 0.8)',
			borderColor: '#fff',
			textStyle: {
				color: '#fff'
			},
			formatter: function (params: any) {
				return `坐标: (${Math.round(params.data[0])}, ${Math.round(params.data[1])})<br/>强度: ${Math.round(params.data[2])}`
			}
		}
	})
}

const generateRandomData = () => {
	if (!chart) return
	
	const data = []
	const width = 600
	const height = 400
	
	// 生成随机数据
	for (let i = 0; i < 500; i++) {
		data.push([
			Math.random() * width,
			Math.random() * height,
			Math.random() * 100
		])
	}
	
	chart.setOption({
		backgroundColor: '#000',
		title: {
			text: '平滑热力图 - 随机数据',
			left: 'center',
			top: 10,
			textStyle: {
				color: '#fff',
				fontSize: 16
			}
		},
		grid: {
			left: 0,
			right: 0,
			top: 40,
			bottom: 0
		},
		xAxis: {
			type: 'value',
			min: 0,
			max: 600,
			show: false
		},
		yAxis: {
			type: 'value',
			min: 0,
			max: 400,
			show: false
		},
		visualMap: {
			min: 0,
			max: 100,
			show: false,
			inRange: {
				color: [
					'#313695',
					'#4575b4',
					'#74add1',
					'#abd9e9',
					'#e0f3f8',
					'#ffffbf',
					'#fee090',
					'#fdae61',
					'#f46d43',
					'#d73027',
					'#a50026'
				]
			}
		},
		series: [{
			name: '随机数据',
			type: 'scatter',
			data: data,
			symbolSize: function(data: any) {
				return Math.max(10, Math.min(40, data[2] * 0.5 + 10))
			},
			itemStyle: {
				opacity: 0.5
			},
			label: {
				show: false
			},
			animation: false
		}]
	})
}

const generateSmoothData = () => {
	if (!chart) return
	
	const data = []
	const width = 300
	const height = 200
	
	// 超高密度数据点，创建平滑效果
	for (let i = 0; i < width; i += 2) {
		for (let j = 0; j < height; j += 2) {
			// 使用多个高斯函数叠加创建平滑效果
			const x = (i - width/2) / 100
			const y = (j - height/2) / 100
			
			// 多个高斯函数叠加，模拟图片中的热点
			const value1 = 80 * Math.exp(-((x-1.5)**2 + (y-0.3)**2) / 0.4)  // 右上大热点
			const value2 = 60 * Math.exp(-((x+1.8)**2 + (y-0.8)**2) / 0.3)  // 左上小热点
			const value3 = 55 * Math.exp(-((x+1.5)**2 + (y+0.8)**2) / 0.35) // 左下小热点
			const value4 = 40 * Math.exp(-((x+0.3)**2 + (y)**2) / 0.6)      // 中间连接
			const value5 = 45 * Math.exp(-((x+1.2)**2 + (y+0.2)**2) / 0.25) // 右下小热点
			
			const totalValue = value1 + value2 + value3 + value4 + value5
			
			// 添加微小的随机噪声
			const noise = (Math.random() - 0.5) * 2
			const finalValue = totalValue + noise
			
			// 保留更多低值点，创建渐变效果
			if (finalValue > 1) {
				data.push([i, j, finalValue])
			}
		}
	}
	
	// 输出数据量统计
	console.log(`生成的数据点数量: ${data.length}`)
	console.log(`图表尺寸: ${width}x${height}`)
	console.log(`数据大小估算: ${(data.length * 3 * 8 / 1024).toFixed(2)} KB`) // 每个数字按8字节计算
	
	// 打印前20个数据点作为示例
	console.log('前20个数据点示例:')
	console.log(data.slice(0, 20))
	
	// 打印完整数据（注意：数据量大时会很长）
	console.log('完整数据:')
	console.log(JSON.stringify(data, null, 2))
	
	chart.setOption({
		backgroundColor: '#000',
		title: {
			text: '超平滑热力图 - 密集数据',
			left: 'center',
			top: 10,
			textStyle: {
				color: '#fff',
				fontSize: 16
			}
		},
		grid: {
			left: 0,
			right: 0,
			top: 40,
			bottom: 0
		},
		xAxis: {
			type: 'value',
			min: 0,
			max: 300,
			show: false
		},
		yAxis: {
			type: 'value',
			min: 0,
			max: 200,
			show: false
		},
		visualMap: {
			min: 0,
			max: 80,
			show: false,
			inRange: {
				color: [
					'#000040',
					'#0000FF',
					'#0080FF',
					'#00FF80',
					'#80FF00',
					'#FFFF00',
					'#FF8000',
					'#FF4000',
					'#FF0000'
				]
			}
		},
		series: [{
			name: '超平滑数据',
			type: 'scatter',
			data: data,
			symbolSize: function(data: any) {
				// 较大的点，让覆盖更充分形成平滑效果
				return Math.max(8, Math.min(20, data[2] * 0.3 + 8))
			},
			itemStyle: {
				opacity: 0.4
			},
			label: {
				show: false
			},
			animation: false
		}]
	})
}

const generateBlendedData = () => {
	if (!chart) return
	
	const data = []
	const width = 600
	const height = 400
	
	// 创建几个主要的热点区域
	const hotspots = [
		{ x: 150, y: 100, intensity: 80, radius: 120 },
		{ x: 450, y: 150, intensity: 70, radius: 100 },
		{ x: 300, y: 300, intensity: 60, radius: 90 },
		{ x: 100, y: 280, intensity: 50, radius: 80 }
	]
	
	// 使用更稀疏的采样，但更大的点
	for (let i = 0; i < width; i += 15) {
		for (let j = 0; j < height; j += 15) {
			let maxIntensity = 0
			
			// 计算该点受到的最大热力影响
			hotspots.forEach(hotspot => {
				const distance = Math.sqrt((i - hotspot.x) ** 2 + (j - hotspot.y) ** 2)
				const intensity = hotspot.intensity * Math.exp(-distance / hotspot.radius)
				maxIntensity = Math.max(maxIntensity, intensity)
			})
			
			// 添加一些随机背景热力
			const background = Math.random() * 8
			const finalValue = maxIntensity + background
			
			// 只保留有明显热力的点
			if (finalValue > 10) {
				data.push([i, j, finalValue])
			}
		}
	}
	
	chart.setOption({
		backgroundColor: '#000',
		title: {
			text: '混合热力图 - 大区域覆盖',
			left: 'center',
			top: 10,
			textStyle: {
				color: '#fff',
				fontSize: 16
			}
		},
		grid: {
			left: 0,
			right: 0,
			top: 40,
			bottom: 0
		},
		xAxis: {
			type: 'value',
			min: 0,
			max: 600,
			show: false
		},
		yAxis: {
			type: 'value',
			min: 0,
			max: 400,
			show: false
		},
		visualMap: {
			min: 0,
			max: 80,
			show: false,
			inRange: {
				color: [
					'rgba(0, 0, 139, 0.1)',
					'rgba(0, 100, 255, 0.3)',
					'rgba(0, 191, 255, 0.5)',
					'rgba(255, 255, 0, 0.7)',
					'rgba(255, 165, 0, 0.8)',
					'rgba(255, 0, 0, 0.9)'
				]
			}
		},
		series: [{
			name: '混合热力图',
			type: 'scatter',
			data: data,
			symbolSize: function(data: any) {
				// 非常大的点，让覆盖更充分
				return Math.max(60, Math.min(120, data[2] * 1.5 + 60))
			},
			itemStyle: {
				opacity: 0.8
			},
			label: {
				show: false
			},
			animation: false
		}]
	})
}
</script>

<style scoped>
.test-container {
	padding: 20px;
	max-width: 800px;
	margin: 0 auto;
}

.heatmap-container {
	width: 300px;
	height: 200px;
	margin: 20px auto;
	border: 2px solid #333;
	border-radius: 8px;
	background: #000;
}

.controls {
	text-align: center;
	margin-top: 20px;
}

.controls button {
	margin: 0 10px;
	padding: 10px 20px;
	background: #2176b8;
	color: white;
	border: none;
	border-radius: 5px;
	cursor: pointer;
}

.controls button:hover {
	background: #1a5d94;
}

h2 {
	text-align: center;
	color: #333;
	margin-bottom: 20px;
}
</style>